package crm.base.dialect;

/**
 * SQL方言(仅用于分页)
 * 
 * @author Zhang Qiongbiao
 *
 */
public abstract class Dialect {
	
	protected static final String FASTPAGE_TAG = "@fastpage";
	protected static final char OPEN_PARENTHESIS = '(';
	protected static final char CLOSE_PARENTHESIS = ')';
	
	private String originalSql;
	protected int offset;
	protected int limit;

	private int fastpageIndex;
	private FastpageSqlParser fastpageSqlParser;
	
	public void init(String originalSql, int offset, int limit) {
		this.originalSql = originalSql;
		this.offset = offset;
		this.limit = limit;

		this.fastpageIndex = originalSql.indexOf(FASTPAGE_TAG);
		if (fastpageIndex > -1) {
			fastpageSqlParser = new FastpageSqlParser();
		}
	}
	
	/**
	 * 分页部分sql具体实现方法
	 */
	protected abstract String pagingSqlParser(String sql);
	
	/**
	 * 统计分页部分记录数sql具体实现方法
	 */
	protected abstract String totalCountSqlParser(String sql);
	
	/**
	 * 获取分页sql
	 * @return
	 */
	public String getLimitString() {
		// 普通sql处理
		if (fastpageIndex == -1) {
			return pagingSqlParser(originalSql);
		}

		// 存在@fastpage标签的sql处理
		return fastpageSqlParser.getFinalSql(pagingSqlParser(fastpageSqlParser.getFastpageSql()));
	}

	/**
	 * 获取统计总记录sql
	 * @return
	 */
	public String getTotalCountString() {
		// 普通sql处理
		if (fastpageIndex == -1) {
			return totalCountSqlParser(originalSql);
		}
		
		// 存在@fastpage标签的sql处理
		return totalCountSqlParser(fastpageSqlParser.getFastpageSql());
	}
	
	/**
	 * fastpage具体解析类
	 */
	class FastpageSqlParser {
		private StringBuffer finalSql;
		private StringBuffer fastpageSql;
		
		private int pagingSqlStartIndex; // 括号内分页部分sql起始index
		
		public FastpageSqlParser() {
			finalSql = new StringBuffer(originalSql);
			sqlParser();
		}
		
		public void sqlParser() {
			fastpageSql = new StringBuffer();
			fastpageIndex = originalSql.indexOf(FASTPAGE_TAG);
			int openParenthesisIndex = originalSql.indexOf(String.valueOf(OPEN_PARENTHESIS), fastpageIndex);
			pagingSqlStartIndex = openParenthesisIndex + 1; 
			
			int count = 0; // 用于括号匹配
			for (int i = pagingSqlStartIndex; i < originalSql.length(); i++) {
				char ch = originalSql.charAt(i);
				
				if (ch == CLOSE_PARENTHESIS) {
					if (count == 0) {
						break;
					}
					count--;
				} else if (ch == OPEN_PARENTHESIS) {
					count++;
				}
				fastpageSql.append(ch);
				finalSql.deleteCharAt(pagingSqlStartIndex); // 删除字符后finalSql长度改变,所以这里只需循环删除当前字符
			}
		}

		public String getFinalSql(String pagingSql) {
			finalSql.insert(pagingSqlStartIndex, pagingSql);
			finalSql.delete(fastpageIndex, fastpageIndex + FASTPAGE_TAG.length());
			
			return finalSql.toString();
		}

		public String getFastpageSql() {
			return fastpageSql.toString();
		}
	}
}
